package com.biyabi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.biyabi.dao.*;
import com.biyabi.entity.*;
import com.biyabi.pojo.ProductPojo;
import com.biyabi.pojo.ProductsData;
import com.biyabi.pojo.SkuPojo;
import com.biyabi.service.CatelogService;
import com.biyabi.service.ProductService;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Service
@Transactional
public class ProductServiceImpl implements ProductService {
    @Resource
    private CatelogBrandMapper catelogBrandMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private PritureMapper pritureMapper;
    @Resource
    private ColorMapper colorMapper;
    @Resource
    private SizeMapper sizeMapper;
    @Resource
    private SkuMapper skuMapper;
    @Resource
    private BrandMapper brandMapper;
    @Resource
    private CatelogMapper catelogMapper;
    @Resource
    private SupplierMapper supplierMapper;
    @Resource
    private CatelogService catelogService;

    @Override
    public void add(Product product, MultipartFile addProductCover, MultipartFile[] addProductTop, MultipartFile[] addProductDown, String catelogId, String brandId, String skuPojo, HttpServletRequest request) {
        try {
            String coverRealPath = request.getSession().getServletContext().getRealPath("/upload/cover");
            String ImageRealPath = request.getSession().getServletContext().getRealPath("/upload/image");
            addProductCover.transferTo(new File(coverRealPath+"/"+addProductCover.getOriginalFilename()));
            product.setCover("upload/cover/"+addProductCover.getOriginalFilename());
            product.setId(UUID.randomUUID().toString());
            product.setLikes(0);
            CatelogBrandExample catelogBrandExample = new CatelogBrandExample();
            catelogBrandExample.createCriteria().andBrandidEqualTo(brandId).andCatelogidEqualTo(catelogId);
            List<CatelogBrand> catelogBrands = catelogBrandMapper.selectByExample(catelogBrandExample);
            String catelogBrandId;
            if(catelogBrands.size()==0){
                CatelogBrand catelogBrand = new CatelogBrand();
                catelogBrand.setId(UUID.randomUUID().toString());
                catelogBrand.setBrandid(brandId);
                catelogBrand.setCatelogid(catelogId);
                catelogBrandMapper.insert(catelogBrand);
                catelogBrandId = catelogBrand.getId();
            }else{
                catelogBrandId = catelogBrands.get(0).getId();
            }
            product.setCatelogbrankid(catelogBrandId);
            List<SkuPojo> skuPojos = JSONObject.parseArray(skuPojo, SkuPojo.class);
            skuPojos.sort(new MyComparator());
            product.setReduction(0.0);
            product.setMaxprice(skuPojos.get(skuPojos.size()-1).getOriginPrice()*skuPojos.get(skuPojos.size()-1).getDiscount()/100.0);
            product.setMinprice(skuPojos.get(0).getOriginPrice()*skuPojos.get(0).getDiscount()/100.0);
            productMapper.insert(product);


            for (MultipartFile multipartFile : addProductTop) {
                Priture priture = new Priture();
                priture.setId(UUID.randomUUID().toString());
                priture.setIstop(1);
                priture.setProductid(product.getId());
                multipartFile.transferTo(new File(ImageRealPath+"/"+multipartFile.getOriginalFilename()));
                priture.setPath("/upload/image/"+multipartFile.getOriginalFilename());
                pritureMapper.insert(priture);
            }
            for (MultipartFile multipartFile : addProductDown) {
                Priture priture = new Priture();
                priture.setId(UUID.randomUUID().toString());
                priture.setIstop(0);
                priture.setProductid(product.getId());
                multipartFile.transferTo(new File(ImageRealPath+"/"+multipartFile.getOriginalFilename()));
                priture.setPath("/upload/image/"+multipartFile.getOriginalFilename());
                pritureMapper.insert(priture);
            }
            for (SkuPojo pojo : skuPojos) {
                ColorExample colorExample = new ColorExample();
                colorExample.createCriteria().andNameEqualTo(pojo.getColor());
                List<Color> colors = colorMapper.selectByExample(colorExample);
                String colorId;
                if(colors.size()==0){
                    Color color = new Color();
                    color.setId(UUID.randomUUID().toString());
                    color.setName(pojo.getColor());
                    colorMapper.insert(color);
                    colorId = color.getId();
                }else{
                    colorId = colors.get(0).getName();
                }
                SizeExample sizeExample = new SizeExample();
                sizeExample.createCriteria().andNameEqualTo(pojo.getSize());
                List<Size> sizes = sizeMapper.selectByExample(sizeExample);
                String sizeId;
                if(sizes.size()==0){
                    Size size = new Size();
                    size.setId(UUID.randomUUID().toString());
                    size.setName(pojo.getSize());
                    sizeMapper.insert(size);
                    sizeId = size.getId();
                }else{
                    sizeId = sizes.get(0).getId();
                }

                SkuExample skuExample = new SkuExample();
                skuExample.createCriteria().andColoridEqualTo(colorId).andSizeidEqualTo(sizeId);
                List<Sku> skus = skuMapper.selectByExample(skuExample);
                if(skus.size() == 0){
                    Sku sku = new Sku();
                    sku.setId(UUID.randomUUID().toString());
                    sku.setColorid(colorId);
                    sku.setSizeid(sizeId);
                    sku.setCount(pojo.getCount());
                    sku.setDiscount(pojo.getDiscount()/100.0);
                    sku.setImage("/upload/cover/"+pojo.getImage().substring(pojo.getImage().lastIndexOf("/")+1));
                    sku.setOriginprice(pojo.getOriginPrice());
                    sku.setProductid(product.getId());
                    sku.setWeight(pojo.getWeight());
                    skuMapper.insert(sku);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }
    @Override
    public void update(Product product, MultipartFile[] updateProductTop, MultipartFile[] updateProductDown, String productStatus, String catelogId, String brandId, String skuPojo, HttpServletRequest request) {
        try {
            String coverRealPath = request.getSession().getServletContext().getRealPath("/upload/cover");
            String ImageRealPath = request.getSession().getServletContext().getRealPath("/upload/image");
            Product product1 = productMapper.selectByPrimaryKey(product.getId());
            product.setMaxprice(product1.getMaxprice());
            product.setReduction(product1.getReduction());
            product.setLikes(product1.getLikes());
            product.setMinprice(product1.getMinprice());

            if('/'==product.getCover().charAt(0)){
                product.setCover(product.getCover().substring(1));
            }
            CatelogBrandExample catelogBrandExample = new CatelogBrandExample();
            catelogBrandExample.createCriteria().andBrandidEqualTo(brandId).andCatelogidEqualTo(catelogId);
            List<CatelogBrand> catelogBrands = catelogBrandMapper.selectByExample(catelogBrandExample);
            String catelogBrandId;
            if(catelogBrands.size()==0){
                CatelogBrand catelogBrand = new CatelogBrand();
                catelogBrand.setId(UUID.randomUUID().toString());
                catelogBrand.setBrandid(brandId);
                catelogBrand.setCatelogid(catelogId);
                catelogBrandMapper.insert(catelogBrand);
                catelogBrandId = catelogBrand.getId();
            }else{
                catelogBrandId = catelogBrands.get(0).getId();
            }
            product.setCatelogbrankid(catelogBrandId);
            List<SkuPojo> skuPojos = JSONObject.parseArray(skuPojo, SkuPojo.class);
            skuPojos.sort(new MyComparator());
            product.setMaxprice(skuPojos.get(skuPojos.size()-1).getOriginPrice()*skuPojos.get(skuPojos.size()-1).getDiscount()/100.0);
            product.setMinprice(skuPojos.get(0).getOriginPrice()*skuPojos.get(0).getDiscount()/100.0);

            product.setReduction((product1.getMaxprice()- product.getMaxprice())/product1.getMaxprice());
            productMapper.updateByPrimaryKey(product);
            if(updateProductTop.length>0){
                if(!updateProductTop[0].isEmpty()){
                    PritureExample example = new PritureExample();
                    example.createCriteria().andProductidEqualTo(product.getId()).andIstopEqualTo(1);
                    pritureMapper.deleteByExample(example);
                }
                for (MultipartFile multipartFile : updateProductTop) {
                    if(!multipartFile.isEmpty()){
                        Priture priture = new Priture();
                        priture.setId(UUID.randomUUID().toString());
                        priture.setIstop(1);
                        priture.setProductid(product.getId());
                        multipartFile.transferTo(new File(ImageRealPath+"/"+multipartFile.getOriginalFilename()));
                        priture.setPath("/upload/image/"+multipartFile.getOriginalFilename());
                        pritureMapper.insert(priture);
                    }
                }
            }
            if(updateProductDown.length>0){
                if(!updateProductTop[0].isEmpty()){
                    PritureExample example = new PritureExample();
                    example.createCriteria().andProductidEqualTo(product.getId()).andIstopEqualTo(0);
                    pritureMapper.deleteByExample(example);
                }
                for (MultipartFile multipartFile : updateProductDown) {
                    if(!multipartFile.isEmpty()) {
                        Priture priture = new Priture();
                        priture.setId(UUID.randomUUID().toString());
                        priture.setIstop(0);
                        priture.setProductid(product.getId());
                        multipartFile.transferTo(new File(ImageRealPath + "/" + multipartFile.getOriginalFilename()));
                        priture.setPath("/upload/image/" + multipartFile.getOriginalFilename());
                        pritureMapper.insert(priture);
                    }
                }
            }
            SkuExample example = new SkuExample();
            example.createCriteria().andProductidEqualTo(product.getId());
            skuMapper.deleteByExample(example);
            for (SkuPojo pojo : skuPojos) {
                System.out.println(pojo);
                ColorExample colorExample = new ColorExample();
                colorExample.createCriteria().andNameEqualTo(pojo.getColor());
                List<Color> colors = colorMapper.selectByExample(colorExample);
                String colorId;
                if(colors.size()==0){
                    Color color = new Color();
                    color.setId(UUID.randomUUID().toString());
                    color.setName(pojo.getColor());
                    colorMapper.insert(color);
                    colorId = color.getId();
                }else{
                    colorId = colors.get(0).getId();
                }
                SizeExample sizeExample = new SizeExample();
                sizeExample.createCriteria().andNameEqualTo(pojo.getSize());
                List<Size> sizes = sizeMapper.selectByExample(sizeExample);
                String sizeId;
                if(sizes.size()==0){
                    Size size = new Size();
                    size.setId(UUID.randomUUID().toString());
                    size.setName(pojo.getSize());
                    sizeMapper.insert(size);
                    sizeId = size.getId();
                }else{
                    sizeId = sizes.get(0).getId();
                }

                SkuExample skuExample = new SkuExample();
                skuExample.createCriteria().andColoridEqualTo(colorId).andSizeidEqualTo(sizeId).andProductidEqualTo(product.getId());
                List<Sku> skus = skuMapper.selectByExample(skuExample);
                if(skus.size() == 0){
                    Sku sku = new Sku();
                    sku.setId(UUID.randomUUID().toString());
                    sku.setColorid(colorId);
                    sku.setSizeid(sizeId);
                    sku.setCount(pojo.getCount());
                    sku.setDiscount(pojo.getDiscount()/100.0);
                    sku.setImage("/upload/cover/"+pojo.getImage().substring(pojo.getImage().lastIndexOf("/")+1));
                    sku.setOriginprice(pojo.getOriginPrice());
                    sku.setProductid(product.getId());
                    sku.setWeight(pojo.getWeight());
                    skuMapper.insert(sku);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    public ProductsData findAll(Integer currentPage, Integer pageSize, String columnName, String columnValue) {
        currentPage = currentPage == null ? 1:currentPage;
        pageSize= pageSize== null ? 20:pageSize;
        ProductExample productExample = new ProductExample();
        if(columnName!=null && columnValue!=null){
            switch (columnName){
                case "name":
                    productExample.createCriteria().andNameLike("%"+columnValue+"%");
                    break;
                case "introduction":
                    productExample.createCriteria().andIntroductionLike("%"+columnValue+"%");
                    break;
                case "status":
                    productExample.createCriteria().andStatusEqualTo("0".equals(columnValue)?0:1);
                    break;
                case "supplierId":
                    SupplierExample example = new SupplierExample();
                    example.createCriteria().andNameLike("%"+columnValue+"%");
                    List<Supplier> suppliers = supplierMapper.selectByExample(example);
                    ArrayList<String> strings = new ArrayList<>();
                    for (Supplier supplier : suppliers) {
                        strings.add(supplier.getId());
                    }
                    if(strings.size()>0){
                        productExample.createCriteria().andSupplieridIn(strings);
                    }
                    break;

            }
        }
        ProductsData productsData = new ProductsData();
        productsData .setTotal(productMapper.countByExample(productExample));
        PageHelper.startPage(currentPage,pageSize);
        List<Product> products = productMapper.selectByExample(productExample);
        List<ProductPojo> productPojos = new ArrayList<ProductPojo>();

        for (Product product : products) {
            ProductPojo productPojo = beanToPojo(product);
            productPojos.add(productPojo);
        }
        productsData.setRows(productPojos);
        return productsData ;
    }

    @Override
    public List<ProductPojo> findByKey(String key, String orderType, Integer currentPage, Integer pageSize) {
        currentPage = currentPage == null ? 1:currentPage;
        pageSize= pageSize== null ? 20:pageSize;
        ProductExample productExample = new ProductExample();
        productExample.createCriteria().andNameLike("%"+key+"%");
        productExample.setOrderByClause(" order by originPrice*discount "+ orderType);
        PageHelper.startPage(currentPage,pageSize);
        List<Product> products = productMapper.selectByExample(productExample);
        List<ProductPojo> productPojos = new ArrayList<ProductPojo>();

        for (Product product : products) {
            ProductPojo productPojo = beanToPojo(product);
            productPojos.add(productPojo);
        }
        return productPojos ;
    }


    public List<ProductPojo> findAllByCatelog(String catelogId,String brandId,String orderType,Integer currentPage,Integer pageSize){
        currentPage = currentPage == null ? 1 : currentPage ;
        pageSize= pageSize== null ? 20 : pageSize;
        int start = (currentPage - 1)*pageSize;
        int end = currentPage * pageSize-1;
        List<Product> data= new ArrayList<Product>();
        List<Product> products= new ArrayList<Product>();
        if(!catelogId.isEmpty()){
            List<Catelog> lastChildrens =catelogService.getLastChildrens(catelogId);
            for(Catelog catelog:lastChildrens ){
                CatelogBrandExample example = new CatelogBrandExample();
                example.createCriteria().andBrandidLike("%"+brandId+"%").andCatelogidLike("%"+catelog.getId()+"%");
                List<CatelogBrand> catelogBrands=catelogBrandMapper.selectByExample(example);//动态sql为空没有where语句
                for(CatelogBrand catelogBrand:catelogBrands){
                    ProductExample example1 = new ProductExample();
                    example1.createCriteria().andCatelogbrankidEqualTo(catelogBrand.getId());
                    products.addAll(productMapper.selectByExample(example1));
                }
            }
        }else{
            CatelogBrandExample example = new CatelogBrandExample();
            example.createCriteria().andBrandidLike("%"+brandId+"%");
            List<CatelogBrand> catelogBrands=catelogBrandMapper.selectByExample(example);
            for(CatelogBrand catelogBrand:catelogBrands){
                ProductExample example1 = new ProductExample();
                example1.createCriteria().andCatelogbrankidEqualTo(catelogBrand.getId());
                products.addAll(productMapper.selectByExample(example1));
            }
        }
        if(!orderType.isEmpty()){
            products.sort(new ProductComparator());//Product实体类重写compareTo方法
            if("desc".equals(orderType)){
                Collections.reverse(products);
            }
        }
        for(int i= start ; i<end;i++){
            data.add(products.get(i));
        }
        List<ProductPojo> productPojos = new ArrayList<ProductPojo>();

        for (Product product : data) {
            ProductPojo productPojo = beanToPojo(product);
            productPojos.add(productPojo);
        }
        return productPojos ;
    }

    @Override
    public ProductPojo findOne(String id) {
        return beanToPojo(productMapper.selectByPrimaryKey(id));
    }

    public ProductPojo beanToPojo(Product product){
        ProductPojo productPojo = new ProductPojo();
        productPojo.setProduct(product);
        CatelogBrand catelogBrand = catelogBrandMapper.selectByPrimaryKey(product.getCatelogbrankid());
        productPojo.setBrand(brandMapper.selectByPrimaryKey(catelogBrand.getBrandid()));
        productPojo.setCatelog(catelogMapper.selectByPrimaryKey(catelogBrand.getCatelogid()));
        productPojo.setSupplier(supplierMapper.selectByPrimaryKey(product.getSupplierid()));
        PritureExample pritureExample = new PritureExample();
        pritureExample.createCriteria().andProductidEqualTo(product.getId()).andIstopEqualTo(1);
        List<Priture> tops = pritureMapper.selectByExample(pritureExample);
        PritureExample pritureExample1 = new PritureExample();
        pritureExample1.createCriteria().andProductidEqualTo(product.getId()).andIstopEqualTo(0);
        List<Priture> downs = pritureMapper.selectByExample(pritureExample1);
        productPojo.setTops(tops);
        productPojo.setDowns(downs);
        SkuExample skuExample = new SkuExample();
        skuExample.createCriteria().andProductidEqualTo(product.getId());
        List<Sku> skus = skuMapper.selectByExample(skuExample);
        System.out.println(skus.size());
        ArrayList<SkuPojo> skuPojos = new ArrayList<>();
        for (Sku sku : skus) {
            SkuPojo skuPojo = new SkuPojo();
            skuPojo.setId(sku.getId());
            skuPojo.setColor(colorMapper.selectByPrimaryKey(sku.getColorid()).getName());
            skuPojo.setSize(sizeMapper.selectByPrimaryKey(sku.getSizeid()).getName());
            skuPojo.setCount(sku.getCount());
            skuPojo.setDiscount(sku.getDiscount());
            skuPojo.setImage(sku.getImage());
            skuPojo.setOriginPrice(sku.getOriginprice());
            skuPojo.setWeight(sku.getWeight());
            skuPojos.add(skuPojo);
        }
        productPojo.setSkuPojos(skuPojos);
        return productPojo;
    }
}

class ProductComparator implements  Comparator<Product>{
    @Override
    public int compare(Product o1, Product o2) {
        return (int)(o1.getMinprice()-o2.getMinprice());
    }
}

class MyComparator implements Comparator<SkuPojo>{
    @Override
    public int compare(SkuPojo o1, SkuPojo o2) {
        return (int)(o1.getOriginPrice()*o1.getDiscount()-o2.getOriginPrice()*o2.getDiscount());
    }
}